<?PHP
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/

	// Establish some vars
	$json_output = array();

	// Load vars input from the client
	$lastUpdateTime = (float)x7in::get($_GET,'lastUpdateTime');
	$updatecount = x7in::get($_GET,'updatecount','i');
	$rooms = explode(';',x7in::get($_GET,'rooms'));
	$first_run = explode(';',x7in::get($_GET,'initiate'));
	$operations = x7in::get($_GET,'operations','a');

	// Check for any rooms we are leaving
	if(isset($operations['part'])){
		foreach($operations['part'] as $rid){
			$room = new lib_room($rid);
			$room->part($ses->user);
		}
	}

	// Load global messages, primarily database changes to rooms and groups but sometimes a global message
	for($pos = 0; $data = $GLOBALS['CACHE']->getline("messages",$pos); $pos++){
		if(!isset($data['lastUpdateTime']) || $data['lastUpdateTime'] <= $lastUpdateTime) break;
		array_unshift($json_output,$data);
	}

	// Go through each room the user is in and perform the appropriate actions
	foreach($rooms as $rid){

		$room = new lib_room($rid);
		if($room->is_valid()){
			$is_first_run = in_array($rid,$first_run);

			if(!$room->has_permission($ses->user,'PASSWORD_CORRECT')){
				// They do not have access to this room
				$json_output[] = array('lastUpdateTime'=>0,'operation'=>'redirect','data'=>array('close_room'=>$rid,'new_window_id'=>"{$rid}pwreq",'new_window_label'=>$room->data_cache['name'],'new_window_url'=>"./index.php?act=pwreq&rid={$room->data_cache['rid']}{$ses->session_string}"));
			}elseif(!$room->has_permission($ses->user,'ACCESS_ROOM') && !($is_first_run && $room->check_ban_expiration($ses->user->data_cache['uid'])) && !$ses->user->has_permission('BAN_IMMUNITY')){
				// They are banned from this room
				$json_output[] = array('lastUpdateTime'=>0,'operation'=>'redirect','data'=>array('close_room'=>$rid,'new_window_id'=>"{$rid}banned",'new_window_label'=>$room->data_cache['name'],'new_window_url'=>"./index.php?act=error{$ses->session_string}&error=".base64_encode($GLOBALS['OUTPUT']->lang['room_ban'])));
			}else{
				// ok to procede with room, ensure that the cache is up to date
				//if(!$GLOBALS['CACHE']->group_exists("online"))
				//	$GLOBALS['CACHE']->create_group("online");
				
				//if(!$GLOBALS['CACHE']->group_exists("online/{$rid}"))
				//	$GLOBALS['CACHE']->create_group("online/{$rid}");

				// Update online time
				$GLOBALS['CACHE']->settime("online/{$rid}/{$ses->user->data_cache['uid']}");

				// Check to make sure everyone is still living, adding the room id to the update count prevents
				// all checks from being done on the same update.
				if($is_first_run || !(($updatecount+$rid) % $settings['sync_onlinelist_counts'])){
					$users = $room->get_online_users();

					if($is_first_run && !$room->has_permission($ses->user,'ENTER_FULL_ROOM')){
						// Make capacity check
						if(count($users) > $room->data_cache['max_users'] && $room->data_cache['max_users'] != 0){
							$json_output[] = array('lastUpdateTime'=>0,'operation'=>'redirect','data'=>array('close_room'=>$rid,'new_window_id'=>"{$rid}full",'new_window_label'=>$room->data_cache['name'],'new_window_url'=>"./index.php?act=error{$ses->session_string}&error=".base64_encode($GLOBALS['OUTPUT']->lang['room_full'])));
							continue;
						}
					}

					foreach($users as $key=>$val){
						if($val->is_valid()){
							$data_user = $val->data_cache['uid'] == $ses->user->data_cache['uid'] ? $ses->user->data_cache : $val->get_output();
							$json_output[] = array('lastUpdateTime'=>0,'operation'=>'online_add','data'=>array('rid'=>$rid,'uid'=>$val->data_cache['uid'],'name'=>$val->data_cache['name'],'status'=>$data_user['status']));
							$json_output[] = array('lastUpdateTime'=>0,'database'=>'users','operation'=>'add','index'=>$val->data_cache['uid'],'data'=>$data_user);
						}
					}
				}

				// Handle first run duties
				if($is_first_run){
					$room->join_room();

					// Load a limited number of messages from this room's history
					$displayed = 0;
					for($pos = 0; ($data = $GLOBALS['CACHE']->getline("messages/{$rid}",$pos)) && $displayed < $settings['num_previous_msgs_init']; $pos++){
						if(isset($data['operation']) && $data['operation'] == 'new_message'){
							array_unshift($json_output,$data);
							$displayed++;
						}

						if($pos == 0 && isset($data['lastUpdateTime']) && (!$data['data']['restricted'] || $room->has_permission($ses->user,'READ_UNVOICED_USERS')))
							$json_output[] = array('lastUpdateTime'=>$data['lastUpdateTime'],'operation'=>'update_lastUpdateTime','data'=>array());
					}

					// Show greeting message
					if(!empty($room->data_cache['greeting'])){
						$greet = str_replace('%u',$ses->user->data_cache['name'],$room->data_cache['greeting']);
						$json_output[] = lib_sending::send($room,null,$greet,true);
					}

				}else{
					
					// Load messages and stuff, ensure that cache is up to date
					for($pos = 0; $data = $GLOBALS['CACHE']->getline("messages/{$rid}",$pos); $pos++){
						if(!isset($data['lastUpdateTime']) || $data['lastUpdateTime'] <= $lastUpdateTime) break;

						// Skip messages sent by you
						if($data['operation'] == 'new_message' && (($data['data']['uid'] == $ses->user->data_cache['uid'] && $data['data']['name'] != '') || ($data['data']['restricted'] && !$room->has_permission($ses->user,'READ_UNVOICED_USERS'))))
							continue;
							
						array_unshift($json_output,$data);
					}
				}
			}
		}
	}

	// Check for a buddylist sync
	if($lastUpdateTime == -1 || !(($updatecount+$ses->user->data_cache['uid']) % $settings['sync_onlinelist_counts'])){

		if($ses->user->has_permission('USE_BUDDY_LIST')){

			if(!isset($ses->user->data_cache['buddies'])) $ses->user->data_cache['buddies'] = array();

			foreach($ses->user->data_cache['buddies'] as $uid=>$name){

				if($GLOBALS['CACHE']->exists("private_messages/{$uid}") && $GLOBALS['CACHE']->gettime("private_messages/{$uid}") > $ses->time-$settings['online_expire_seconds']){
					// Online
					$buddy = new lib_user($uid);
					$json_output[] = array('lastUpdateTime'=>0,'operation'=>'online_add','data'=>array('rid'=>'buddylist','uid'=>$uid,'name'=>$name,'status'=>$buddy->data_cache['status']));
					continue;
				}
				
				// Offline
				$json_output[] = array('lastUpdateTime'=>0,'operation'=>'online_remove','data'=>array('uid'=>$uid,'rid'=>'buddylist'));
				
			}

		}

	}

	// Get private messages if this isn't the first load
	$GLOBALS['CACHE']->settime("private_messages/{$ses->user->data_cache['uid']}");
	if($lastUpdateTime != -1){
		for($pos = 0; $data = $GLOBALS['CACHE']->getline("private_messages/{$ses->user->data_cache['uid']}",$pos); $pos++){
			if(!isset($data['lastUpdateTime']) || $data['lastUpdateTime'] <= $lastUpdateTime) break;
			array_unshift($json_output,$data);
		}
	}

	// See if any messages are being sent
	if(isset($operations['message'])){

		foreach($operations['message'] as $key=>$message_in){

			$send2 = (int)$operations['pm2'][$key];
			$type = (int)$operations['sendtype'][$key];

			// Ensure that the user is in the room and that the message is not empty
			if(!empty($message_in) && ($type != 1 || in_array($send2,$rooms))){
				
				$to = ($type == 1 ? new lib_room($send2) : new lib_user($send2));
				if($to->is_valid()){
					
					// See if this needs to be passed off to the IRC-style command handler
					if($message_in[0] == '/'){
						lib_irc::process($message_in,$to,$json_output);
					}else{
						$err = lib_sending::send($to,$ses->user,$message_in);
						
						if($err !== lib_sending::E_NONE)
							$json_output[] = lib_sending::send($to,null,lib_sending::get_error_message($err),true);
					}
				}

			}
		}

	}

	// Export the json_output buffer
	echo "INDATA = " . json_encode($json_output) . ";";
?>